#include "historymessagewidget.h"
#include <QGridLayout>
#include <QPushButton>
#include <QLabel>
#include <QImage>
#include <QPixmap>
#include <QIcon>
#include <QFileDialog>

#include "debug.h"
#include "model/datacenter.h"
#include "toast.h"
#include "soundrecorder.h"

using namespace model;

//表示一个历史消息元素
//历史消息中，有可能是一个文本消息，语音消息，历史图片，文件等，所以用一个工厂来创建
HistoryItem* HistoryItem::createHistoryItem(const Message& message)
{
    //创建对象
    HistoryItem* item = new HistoryItem();
    item->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);

    //创建布局管理器
    QGridLayout* layout = new QGridLayout();
    layout->setVerticalSpacing(0);
    layout->setHorizontalSpacing(10);
    layout->setContentsMargins(0,0,0,0);
    item->setLayout(layout);

    //创建头像
    QPushButton* avatarBtn = new QPushButton();
    avatarBtn->setFixedSize(40,40);
    avatarBtn->setIconSize(QSize(40,40));
    avatarBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    avatarBtn->setIcon(message.sender.avatar);
    avatarBtn->setStyleSheet("QPushButton { border: none; }");

    //创建昵称和时间
    QLabel* nameLabel = new QLabel();
    nameLabel->setText(message.sender.nickname + " | " + message.time);
    nameLabel->setFixedHeight(20); //设置为头像的一半
    nameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    //消息内容部分
    QWidget* contentWidget = new QWidget();
    if(message.messageType == TEXT_TYPE) {
        //文本消息
        QLabel* label = new QLabel();
        label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        //开始文本自动换行
        label->setWordWrap(true);
        //设置消息正文
        label->setText(QString(message.content));
        // 设置让 label 能够自动调整大小
        label->adjustSize();
        contentWidget = label;
    }
    else if (message.messageType == IMAGE_TYPE){
        //图片消息
        contentWidget = new ImageButton(message.fileId, message.content);
    }else if(message.messageType == FILE_TYPE) {
        //文件消息
        contentWidget = new FileLabel(message.fileId, message.content);
    }else if(message.messageType == SPEECH_TYPE) {
        //语音消息
        contentWidget = new SpeechLabel(message.fileId);
    }else {
        LOG() <<"错误的消息类型！ mesageType= " <<message.messageType;
    }

    //将控件添加到布局管理器中
    layout->addWidget(avatarBtn,0,0,2,1);
    layout->addWidget(nameLabel,0,1,1,1);
    layout->addWidget(contentWidget,1,1,5,1);

    return item;
}

HistoryMessageWidget::HistoryMessageWidget(QWidget* parent) :QDialog(parent)
{
    //设置基本耐属性
    this->setFixedSize(600,600);
    this->setWindowTitle("历史消息");
    this->setWindowIcon(QIcon(":/resource/image/logo.png"));
    this->setStyleSheet("QWidget { background-color: rgb(255, 255, 255); }");
    this->setAttribute(Qt::WA_DeleteOnClose);

    //创建布局管理器
    layout = new QGridLayout();
    layout->setSpacing(10);
    layout->setContentsMargins(30,30,30,0);
    this->setLayout(layout);

    //创建单选按钮
    keyRadioBtn = new QRadioButton();
    timeRadioBtn = new QRadioButton();
    keyRadioBtn->setText("按关键字搜索");
    timeRadioBtn->setText("按时间搜索");

    //默认按关键字搜索
    keyRadioBtn->setChecked(true);
    layout->addWidget(keyRadioBtn, 0, 0, 1, 2);
    layout->addWidget(timeRadioBtn, 0, 2, 1, 2);

    //创建搜索框
    searchEdit = new QLineEdit();
    searchEdit->setFixedHeight(50);
    searchEdit->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
    searchEdit->setPlaceholderText("要搜索的关键字");
    searchEdit->setStyleSheet("QLineEdit { border: none; border-radius: 10px; background-color: rgb(240, 240, 240); font-size: 16px; padding-left: 10px; }");
    layout->addWidget(searchEdit,1,0,1,8);

    //创建搜索按钮
    searchBtn = new QPushButton();
    searchBtn->setFixedSize(50,50);
    searchBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    searchBtn->setIconSize(QSize(30,30));
    searchBtn->setIcon(QIcon(":/resource/image/search_icon.png"));
    QString btnStyle = "QPushButton { border: none; background-color: rgb(240,240,240); border-radius: 10px; }";
    btnStyle += "QPushButton:pressed { background-color: rgb(220,220,220); }";
    searchBtn->setStyleSheet(btnStyle);
    layout->addWidget(searchBtn, 1, 8, 1, 1);

    //创建时间空间 一开始隐藏，点击按时间搜索的时候出俩
    begTag = new QLabel();
    begTag->setText("开始时间");
    endTag = new QLabel();
    endTag->setText("结束时间");
    begTimeEdit = new QDateTimeEdit();
    endTimeEdit = new QDateTimeEdit();
    //设置时间格式
    begTimeEdit->setDisplayFormat("yyyy-MM-dd hh:mm");
    endTimeEdit->setDisplayFormat("yyyy-MM-dd hh:mm");
    begTimeEdit->setFixedHeight(40);
    endTimeEdit->setFixedHeight(40);
    begTag->hide();
    endTag->hide();
    begTimeEdit->hide();
    endTimeEdit->hide();


    //创建滚动区
    initScrollArea(layout);

    //设置槽函数
    initSignalSlot();

#if TEST_UI
    for(int i=0; i<5; i++) {
        UserInfo sender;
        sender.userId = "";
        sender.nickname = "张三" + QString::number(i);
        sender.avatar = QIcon(":/resource/image/avatarDefault.png");
        sender.description = "";
        sender.phone = "15310432984";
        Message message = Message::messageFactory(TEXT_TYPE, "", sender, QString("消息内容" + QString::number(i)).toUtf8(), "");
        this->addHistoryMessage(message);
    }
#endif
}

//初始化滚动区
void HistoryMessageWidget::initScrollArea(QGridLayout* layout)
{
    //设置滚动区域对象
    QScrollArea* scrollArea = new QScrollArea();
    scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    scrollArea->setWidgetResizable(true);
    scrollArea->verticalScrollBar()->setStyleSheet("QScrollArea { width: 2px; background-color: rgb(255,255,255); }");
    scrollArea->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal { height: 0; }");
    scrollArea->setStyleSheet("QScrollArea { border: none; }");


    //创建QWidget 持有要加入的对象
    container = new QWidget();
    scrollArea->setWidget(container);

    //创建container的布局管理器
    QVBoxLayout* vlayout = new QVBoxLayout();
    vlayout->setSpacing(10);
    vlayout->setContentsMargins(0,0,0,0);
    vlayout->setAlignment(Qt::AlignTop);
    container->setLayout(vlayout); // 这里是container去设置布局 不是scrollArea去设置

    // 4. 把滚动区加入到整个 layout 中
    layout->addWidget(scrollArea, 2, 0, 1, 9);
}

void HistoryMessageWidget::initSignalSlot()
{
    //处理点击按关键字搜索，将时间空间隐藏出来
    connect(keyRadioBtn,&QRadioButton::clicked,this,[=](){
        //将时间控件隐藏起来
        layout->removeWidget(begTag);
        layout->removeWidget(begTimeEdit);
        layout->removeWidget(endTag);
        layout->removeWidget(endTimeEdit);
        begTag->hide();
        begTimeEdit->hide();
        endTag->hide();
        endTimeEdit->hide();

        //将关键字搜索框显示出来
        layout->addWidget(searchEdit,1,0,1,8);
        searchEdit->show();
    });

    connect(timeRadioBtn, &QRadioButton::clicked, this, [=]() {
        // 关键词搜索框隐藏并从布局中删除掉.
        layout->removeWidget(searchEdit);
        searchEdit->hide();

        // 把时间相关的控件, 添加到布局中, 并且进行显示.
        layout->addWidget(begTag, 1, 0, 1, 1);
        layout->addWidget(begTimeEdit, 1, 1, 1, 3);
        layout->addWidget(endTag, 1, 4, 1, 1);
        layout->addWidget(endTimeEdit, 1, 5, 1, 3);
        begTag->show();
        begTimeEdit->show();
        endTag->show();
        endTimeEdit->show();
    });

    connect(searchBtn, &QPushButton::clicked, this, &HistoryMessageWidget::clickSearchBtn);
}

//添加一个历史元素
void HistoryMessageWidget::addHistoryMessage(const Message& message)
{
    HistoryItem* item = HistoryItem::createHistoryItem(message);
    container->layout()->addWidget(item);
}

void HistoryMessageWidget::clear()
{
    QVBoxLayout* layout = dynamic_cast<QVBoxLayout*>(container->layout());
    for(int i = layout->count()-1; i >= 0; i--) {
        //layout->itemAt(i)获取的类型是QLayoutItem
        QWidget* w = layout->itemAt(i)->widget();
        if(w == nullptr) {
            continue;
        }

        layout->removeWidget(w);
        w->deleteLater();
    }
}

void HistoryMessageWidget::clickSearchBtn()
{
    // 判断是关键字搜索还是时间搜索
    DataCenter* dataCenter = DataCenter::getInstance();
    connect(dataCenter, &DataCenter::searchMessageDone, this, &HistoryMessageWidget::clickSearchBtnDone, Qt::UniqueConnection);

    if(keyRadioBtn->isChecked()) {
        // 按照关键词搜索
        const QString& searchKey = searchEdit->text();
        if (searchKey.isEmpty()) {
            return;
        }
        dataCenter->searchMessageAsync(searchKey);
    } else {
        auto begTime = begTimeEdit->dateTime();
        auto endTime = endTimeEdit->dateTime();
        if (begTime >= endTime) {
            Toast::showMessage("时间错误! 开始时间大于结束时间!");
            return;
        }

        dataCenter->searchMessageByTimeAsync(begTime, endTime);
    }

}

void HistoryMessageWidget::clickSearchBtnDone()
{
    DataCenter* dataCenter = DataCenter::getInstance();
    QList<Message>* messageResult = dataCenter->getSearchMessageResult();
    if (messageResult == nullptr) {
        return;
    }

    // 清空列表数据
    this->clear();

    // 将新数据添加到界面上
    for(const auto& m : *messageResult) {
        this->addHistoryMessage(m);
    }
}

ImageButton::ImageButton(const QString &fileId, const QByteArray &content) : fileId(fileId)
{
    this->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Expanding);
    this->setStyleSheet("QPushButton { border: none; }");

    if(!content.isEmpty()) {
        // 不为空直接显示到界面上
        this->updateUI(fileId,content);
    } else {
        DataCenter* dataCenter = DataCenter::getInstance();
        connect(dataCenter,&DataCenter::getSingleFileDone,this,&ImageButton::updateUI);
        dataCenter->getSingleFileAsync(fileId);
    }
}

void ImageButton::updateUI(const QString &fileId, const QByteArray &content)
{
    if(this->fileId != fileId) {
        return;
    }

    // 如果图片太大，要进行缩放
    QImage image;
    image.loadFromData(content);

    int width = image.width();
    int height = image.height();
    if(width >= 300) {
        width = 300;
        height = ((double)image.height() / image.width()) * width;
    }

    this->resize(width,height);
    this->setIconSize(QSize(width, height));
    QPixmap pixmap = QPixmap::fromImage(image);
    this->setIcon(QIcon(pixmap));
}



FileLabel::FileLabel(const QString &fileId, const QString &fileName) :fileId(fileId),fileName(fileName)
{
    this->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    this->setText("文件" + fileName);
    // 自动换行
    this->setWordWrap(true);
    this->adjustSize();

    DataCenter* dataCenter = DataCenter::getInstance();
    connect(dataCenter,&DataCenter::getSingleFileDone,this,&FileLabel::getContentDone);
    dataCenter->getSingleFileAsync(fileId);
}

void FileLabel::getContentDone(const QString &fileId, const QByteArray &fileContent)
{
    if(this->fileId != fileId) {
        return;
    }

    this->content = fileContent;
    // 此时加载完成
    this->loadDone = true;
}

void FileLabel::mousePressEvent(QMouseEvent *event)
{
    (void)event;
    if(!this->loadDone) {
        Toast::showMessage("文件内容加载中, 请稍后尝试!");
        return;
    }

    QString filePath = QFileDialog::getSaveFileName(this,"另存为",QDir::homePath());
    if(filePath.isEmpty()) {
        LOG() << "用户取消了保存";
        return;
    }

    writeByteArrayToFile(filePath,content);
}

SpeechLabel::SpeechLabel(const QString &fileId) :fileId(fileId)
{
    this->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    this->setText("[语音]");
    this->setAlignment(Qt::AlignTop | Qt::AlignLeft);
    // 自动换行
    this->setWordWrap(true);
    this->adjustSize();

    DataCenter* dataCenter = DataCenter::getInstance();
    connect(dataCenter,&DataCenter::getSingleFileDone,this,&SpeechLabel::getContentDone);
    dataCenter->getSingleFileAsync(fileId);
}

void SpeechLabel::getContentDone(const QString &fileId, const QByteArray &content)
{
    if(this->fileId != fileId) {
        return;
    }

    this->content = content;
    // 此时加载完成
    this->loadDone = true;
}

void SpeechLabel::mousePressEvent(QMouseEvent *event)
{
    (void) event;
    if (!this->loadDone) {
        Toast::showMessage("文件内容加载中, 稍后重试");
        return;
    }

    SoundRecorder* soundRecorder = SoundRecorder::getInstance();
    // 开始播放
    soundRecorder->startPlay(this->content);

}
